 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Common Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/cpl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/

 package org.eclipse.ui.internal.contexts;

 import java.io.IOException ;
 import java.util.ArrayList ;
 import java.util.Collections ;
 import java.util.List ;

 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtension;
 import org.eclipse.core.runtime.IExtensionDelta;
 import org.eclipse.core.runtime.IExtensionRegistry;
 import org.eclipse.core.runtime.IRegistryChangeEvent;
 import org.eclipse.core.runtime.IRegistryChangeListener;
 import org.eclipse.ui.internal.util.ConfigurationElementMemento;

 final class ExtensionContextRegistry extends AbstractContextRegistry {
     private List contextContextBindingDefinitions;
     private List contextDefinitions;
     private IExtensionRegistry extensionRegistry;

     ExtensionContextRegistry(IExtensionRegistry extensionRegistry) {
         if (extensionRegistry == null)
             throw new NullPointerException ();

         this.extensionRegistry = extensionRegistry;

         this
             .extensionRegistry
             .addRegistryChangeListener(new IRegistryChangeListener() {
             public void registryChanged(IRegistryChangeEvent registryChangeEvent) {
                 IExtensionDelta[] extensionDeltas =
                     registryChangeEvent.getExtensionDeltas(
                         Persistence.PACKAGE_PREFIX,
                         Persistence.PACKAGE_BASE);

                 if (extensionDeltas.length != 0)
                     try {
                         load();
                     } catch (IOException eIO) {
                     }
             }
         });

         try {
             load();
         } catch (IOException eIO) {
         }
     }

     private String getNamespace(IConfigurationElement configurationElement) {
         String namespace = null;

         if (configurationElement != null) {
             IExtension extension = configurationElement.getDeclaringExtension();

             if (extension != null)
                 namespace = extension.getNamespace();
         }

         return namespace;
     }

     private void load() throws IOException {
         if (contextContextBindingDefinitions == null)
             contextContextBindingDefinitions = new ArrayList ();
         else
             contextContextBindingDefinitions.clear();

         if (contextDefinitions == null)
             contextDefinitions = new ArrayList ();
         else
             contextDefinitions.clear();

         // TODO deprecated start
 IConfigurationElement[] deprecatedConfigurationElements = extensionRegistry.getConfigurationElementsFor("org.eclipse.ui.acceleratorScopes"); //$NON-NLS-1$

         for (int i = 0; i < deprecatedConfigurationElements.length; i++) {
             IConfigurationElement deprecatedConfigurationElement =
                 deprecatedConfigurationElements[i];
             String name = deprecatedConfigurationElement.getName();

             if ("acceleratorScope".equals(name)) //$NON-NLS-1$
 readContextDefinition(deprecatedConfigurationElement);
         }
         
         deprecatedConfigurationElements = extensionRegistry.getConfigurationElementsFor("org.eclipse.ui.commands"); //$NON-NLS-1$

         for (int i = 0; i < deprecatedConfigurationElements.length; i++) {
             IConfigurationElement deprecatedConfigurationElement =
                 deprecatedConfigurationElements[i];
             String name = deprecatedConfigurationElement.getName();

             if ("scope".equals(name)) //$NON-NLS-1$
 readContextDefinition(deprecatedConfigurationElement);
         }
         // TODO deprecated end

         IConfigurationElement[] configurationElements =
             extensionRegistry.getConfigurationElementsFor(
                 Persistence.PACKAGE_FULL);

         for (int i = 0; i < configurationElements.length; i++) {
             IConfigurationElement configurationElement =
                 configurationElements[i];
             String name = configurationElement.getName();

             if (Persistence.TAG_CONTEXT.equals(name))
                 readContextDefinition(configurationElement);
         }

         boolean contextRegistryChanged = false;

         if (!contextContextBindingDefinitions
             .equals(super.contextContextBindingDefinitions)) {
             super.contextContextBindingDefinitions =
                 Collections.unmodifiableList(contextContextBindingDefinitions);
             contextRegistryChanged = true;
         }

         if (!contextDefinitions.equals(super.contextDefinitions)) {
             super.contextDefinitions =
                 Collections.unmodifiableList(contextDefinitions);
             contextRegistryChanged = true;
         }

         if (contextRegistryChanged)
             fireContextRegistryChanged();
     }

     private void readContextDefinition(IConfigurationElement configurationElement) {
         ContextDefinition contextDefinition =
             Persistence.readContextDefinition(
                 new ConfigurationElementMemento(configurationElement),
                 getNamespace(configurationElement));

         if (contextDefinition != null)
             contextDefinitions.add(contextDefinition);
     }
 }

